<?php


namespace BeReborn\Http;

use Swoole\Coroutine;
use Swoole\Http\Response;

/**
 * Class Context
 * @package Yoc\http
 */
class Context extends BaseContext
{

    protected static $_requests = [];

    protected static $_response = [];


    /**
     * @param $request
     * @return \Swoole\Http\Request
     */
    public static function setRequest($request)
    {
        if (static::inCoroutine()) {
            Coroutine::getContext()['request'] = $request;
        } else {
            static::$_requests['request'] = $request;
        }
        return $request;
    }

    /**
     * @param $id
     * @param $context
     * @param null $key
     * @return mixed
     */
    public static function setContext($id, $context, $key = null)
    {
        if (static::inCoroutine()) {
            if (!static::hasContext($id)) {
                Coroutine::getContext()[$id] = [];
            }
            if (!empty($key)) {
                if (!is_array(Coroutine::getContext()[$id])) {
                    Coroutine::getContext()[$id] = [$key => $context];
                } else {
                    Coroutine::getContext()[$id][$key] = $context;
                }
            } else {
                Coroutine::getContext()[$id] = $context;
            }
        } else {
            if (!empty($key)) {
                if (!is_array(static::$_requests[$id])) {
                    static::$_requests[$id] = [$key => $context];
                } else {
                    static::$_requests[$id][$key] = $context;
                }
            } else {
                static::$_requests[$id] = $context;
            }
        }
        return $context;
    }

    /**
     * @param $id
     * @param null $key
     * @return false|mixed
     */
    public static function autoIncr($id, $key = null)
    {
        if (!static::inCoroutine()) {
            return false;
        }
        if (!isset(Coroutine::getContext()[$id][$key])) {
            return false;
        }
        return Coroutine::getContext()[$id][$key] += 1;
    }

    /**
     * @param $id
     * @param null $key
     * @return false|mixed
     */
    public static function increment($id, $key = null)
    {
        return static::autoIncr($id, $key);
    }


    /**
     * @param $id
     * @param null $key
     * @return false|mixed
     */
    public static function decrement($id, $key = null)
    {
        return static::autoDecr($id, $key);
    }

    /**
     * @param $id
     * @param null $key
     * @return false|mixed
     */
    public static function autoDecr($id, $key = null)
    {
        if (!static::inCoroutine()) {
            return false;
        }
        if (!isset(Coroutine::getContext()[$id][$key])) {
            return false;
        }
        return Coroutine::getContext()[$id][$key] -= 1;
    }

    /**
     * @param $id
     * @param null $key
     * @return mixed
     */
    public static function getContext($id, $key = null)
    {
        if (static::inCoroutine()) {
            $array = Coroutine::getContext()[$id] ?? null;
        } else {
            $array = static::$_requests[$id] ?? null;
        }
        if (empty($key) || !is_array($array)) {
            return $array;
        }
        return $array[$key];
    }

    /**
     * @param $id
     * @return mixed
     */
    public static function getAllContext()
    {
        if (static::inCoroutine()) {
            return Coroutine::getContext() ?? [];
        } else {
            return static::$_requests ?? [];
        }
    }

    /**
     * @param $id
     * @param null $key
     */
    public static function deleteId($id, $key = null)
    {
        if (!static::hasContext($id, $key)) {
            return;
        }
        if (static::inCoroutine()) {
            if (!empty($key)) {
                Coroutine::getContext()[$id][$key] = null;
            } else {
                Coroutine::getContext()[$id] = null;
            }
        } else {
            unset(static::$_requests[$id]);
        }
    }


    public static function remove($id, $key = null)
    {
        static::deleteId($id, $key);
    }

    /**
     * @param $id
     * @param null $key
     * @return mixed
     */
    public static function hasContext($id, $key = null)
    {
        if (static::inCoroutine()) {
            $data = Coroutine::getContext()[$id] ?? null;
        } else {
            $data = static::$_requests[$id] ?? null;
        }
        if (empty($data)) {
            return false;
        }
        if (empty($key)) {
            return true;
        } else if (!is_array($data)) {
            return false;
        }
        return isset($data[$key]);
    }


    /**
     * @return bool
     */
    public static function inCoroutine()
    {
        return Coroutine::getCid() > 0;
    }


    /**
     * @return Request|null
     */
    public static function getRequest()
    {
        if (!static::inCoroutine()) {
            return static::$_requests['request'] ?? null;
        }
        return Coroutine::getContext()['request'] ?? null;
    }


    /**
     * @param Response $response
     * @return Response
     */
    public static function setResponse($response)
    {
        if (static::inCoroutine()) {
            Coroutine::getContext()['response'] = $response;
        } else {
            static::$_response['response'] = $response;
        }
        return $response;
    }


    /**
     * @return Response|null
     */
    public static function getResponse()
    {
        if (!static::inCoroutine()) {
            return static::$_response['response'] ?? null;
        }
        return Coroutine::getContext()['response'] ?? null;
    }

}



